package io.mvvm.ws.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

/**
 * @program: Netty
 * @description: 日志打印处理器
 * @author: 潘
 * @create: 2021-05-14 21:46
 **/
@Component
@ChannelHandler.Sharable
public class WebSocketLoggerHandler extends ChannelInboundHandlerAdapter {

    public static final String HANDLER_NAME = "WebSocketLoggerHandler";

    private static final Logger logger = LoggerFactory.getLogger(WebSocketLoggerHandler.class);

    public WebSocketLoggerHandler() {
        super();
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        String channelId = ctx.channel().id().asShortText();
        boolean active = ctx.channel().isActive();
        logger.info("通道 [ {} ] 被注册, 活跃状态: {}, 客户端IP地址为: {}", channelId, active, getChannelIp(ctx));
        super.channelRegistered(ctx);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        logger.warn("通道 [ {} ] 被注销", ctx.channel().id().asShortText());
        super.channelUnregistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        logger.info("通道 [ {} ] 处理就绪", ctx.channel().id().asShortText());
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.warn("客户端关闭 Socket 连接 [ {} ]", ctx.channel().id().asShortText());
        super.channelInactive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        logger.info("通道 [ {} ] 收到消息: {}", ctx.channel().id().asShortText(), msg);
        super.channelRead(ctx, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        logger.info("通道 [ {} ] 消息读取完毕", ctx.channel().id().asShortText());
        super.channelReadComplete(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        logger.info("通道 [ {} ] 触发 [ {} ] 事件", ctx.channel().id().asShortText(), evt);
        super.userEventTriggered(ctx, evt);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        logger.info("通道 [ {} ] 可写性已更改", ctx.channel().id().asShortText());
        super.channelWritabilityChanged(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("通道 [ {} ] 发生异常: {}", ctx.channel().id().asShortText(), cause.getMessage());
        super.exceptionCaught(ctx, cause);
    }

    @Override
    protected void ensureNotSharable() {
        logger.info("ensureNotSharable");
        super.ensureNotSharable();
    }

    @Override
    public boolean isSharable() {
        logger.info("isSharable");
        return super.isSharable();
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        logger.info("通道 [ {} ] 成功注册处理器 [{}]", ctx.channel().id().asShortText(), this);
        super.handlerAdded(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        logger.warn("通道 [ {} ] 删除处理器 [{}]", ctx.channel().id().asShortText(), this);
        super.handlerRemoved(ctx);
    }


    /**
     * 获取客户端IP
     * @param ctx
     * @return
     */
    private String getChannelIp(ChannelHandlerContext ctx) {
        InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
        return ipSocket.getAddress().getHostAddress();
    }

}
